import { each } from 'lodash';
import { Matrix4, Path, Vector2, Vector3 } from 'three';
import earcut from 'earcut';
import AModelFmulaUtils from './AModelFmulaUtils';
import { BIM } from './BIM';
import { AK } from '../const/ModelConst';
export default class MeshGeomLib {
    static getExpandSplit(vs: Vector3[], num: number, num2: number): any[] {
        let veccc = MeshGeomLib.CalculateNormal(vs, 1);
        let pppps2 = MeshGeomLib.pointExpand(vs, veccc, num, false);
        let pppps3 = MeshGeomLib.pointExpand(vs, veccc, num2, false);
        let pppps4 = MeshGeomLib.pointExpand(pppps2, veccc, -num2, false);

        let v1 = vs[0].clone().sub(vs[1]).normalize();
        v1 = v1.setLength(Math.abs(num2)).add(vs[1]);
        let v2 = vs[vs.length - 1].clone().sub(vs[vs.length - 2]).normalize();
        v2 = v2.setLength(Math.abs(num2)).add(vs[vs.length - 2]);
        let v3 = pppps2[0].clone().sub(pppps2[1]).normalize();
        v3 = v3.setLength(Math.abs(num2)).add(pppps2[1]);
        let v4 = pppps2[pppps2.length - 1].clone().sub(pppps2[pppps2.length - 2]).normalize();
        v4 = v4.setLength(Math.abs(num2)).add(pppps2[pppps2.length - 2]);

        // let i:number;
        // let arr = [...vs,...pppps2.reverse()];
        // for(i=0;i<vs)

        return [];
    }



    static getInt(num: any, num2: number = 1): number {
        let m = Math.pow(10, num2);
        let n = (Math.round(Number(num) * m) / m);
        return n;
    }

    static pointsRotationByPoint(angle: number, arr: Vector3[], pt: Vector3): void {
        let x000;
        let y000;
        for (let i = 0; i < arr.length; i++) {
            x000 = arr[i].x;
            y000 = arr[i].y;
            arr[i].x = (x000 - pt.x) * Math.cos(angle * (Math.PI / 180)) - (y000 - pt.y) * Math.sin(angle * (Math.PI / 180)) + pt.x;
            arr[i].y = (x000 - pt.x) * Math.sin(angle * (Math.PI / 180)) + (y000 - pt.y) * Math.cos(angle * (Math.PI / 180)) + pt.y;
        }
    }

    static getPsLWbyVec3(arr: Vector3[]): number[] {
        let minx = Number.MAX_VALUE;
        let miny = Number.MAX_VALUE;
        let minz = Number.MAX_VALUE;
        let maxx = -9999;
        let maxy = -9999;
        let maxz = -9999;
        let fn;
        for (let i = 0; i < arr.length; i++) {
            fn = arr[i];
            if (fn.x < minx) {
                minx = fn.x;
            }
            if (fn.x > maxx) {
                maxx = fn.x;
            }
            if (fn.y < miny) {
                miny = fn.y;
            }
            if (fn.y > maxy) {
                maxy = fn.y;
            }
            if (fn.z < minz) {
                minz = fn.z;
            }
            if (fn.z > maxz) {
                maxz = fn.z;
            }
        }
        return [minx, miny, minz, maxx, maxy, maxz, maxx - minx, maxy - miny, maxz - minz];
    }

    /**
     * 获取光面孔
     * @param r 
     * @param rpos 
     * @param holes 
     * @param type 0 x 1 y 2 z
     */
    static getGmtHoles(r: string, rpos: string, holes: Path[], type: number = 0, l: number = 0,): void {

        let holePath: Path;
        let cdr: string[];
        let index: number = -1;
        let i: number, xv: number, yv: number, widthR: number, hightR: number, gmtR: number;
        let gmtpos = AModelFmulaUtils.getHolesbyExpress(rpos, 0, 3);
        if (gmtpos && gmtpos.length > 0) {
            for (i = 0; i < gmtpos.length; i++) {

                xv = type === 1 ? gmtpos[i].y : gmtpos[i].x;
                yv = type === 1 ? gmtpos[i].x : gmtpos[i].y;

                index = r.indexOf('*');
                if (index != -1) {
                    cdr = r.split('*');
                    if (type === 1) {
                        widthR = Number(cdr[0]);
                        hightR = Number(cdr[1]);
                    }
                    else {
                        widthR = Number(cdr[1]);
                        hightR = Number(cdr[0]);
                    }


                    gmtR = widthR > hightR ? hightR : widthR;

                    holePath = new Path();
                    if (widthR > hightR) {
                        holePath.moveTo(xv, yv)
                            .absarc(xv + (widthR - hightR) / 2, yv, gmtR / 2, Math.PI * 1.5, Math.PI * 0.5, false)
                            .lineTo(xv - (widthR - hightR) / 2, yv + hightR / 2)
                            .absarc(xv - (widthR - hightR) / 2, yv, gmtR / 2, Math.PI * 0.5, Math.PI * 1.5, false)
                            .lineTo(xv + (widthR - hightR) / 2, yv - hightR / 2)
                    }
                    else {
                        holePath.moveTo(xv, yv)
                            .absarc(xv, yv + (hightR - widthR) / 2, gmtR / 2, 0, Math.PI, false)
                            .lineTo(xv - widthR / 2, yv - (hightR - widthR) / 2)
                            .absarc(xv, yv - (hightR - widthR) / 2, gmtR / 2, Math.PI, Math.PI * 2, false)
                            .lineTo(xv + widthR / 2, yv + (hightR - widthR) / 2)
                    }
                }
                else {
                    gmtR = Number(r);

                    holePath = new Path();
                    holePath.moveTo(xv, yv)
                        .absarc(xv, yv, gmtR / 2, 0, Math.PI * 2, true);
                }
                holes.push(holePath);
            }
        }
    }
    // static getFaceHoleNs3(vs: Vector3[], vs2: Vector3[], arr: any[], type: number = 1, angle: number = 0, dir: Vector3 = new Vector3(1, 1, 1), kongs: number[] = null, faces: any[] = null, key: string = ''): any {
    //     let i: number, j: number, circle: any, vv: Vector3;
    //     let ns: number[] = [];
    //     let newvs: number[] = [];
    //     let ppppppppsss: Vector3[] = [], ks: Vector3[] = [];
    //     let ppppppppsss2: Vector3[] = [];
    //     let ppppppppsss3: Vector3[] = [];
    //     for (i = 0; i < vs.length; i++) {
    //         if (type === 1) {
    //             ns.push(vs[i].x, vs[i].z, vs[i].y);
    //             newvs.push(vs2[i].x, vs2[i].z, vs2[i].y);
    //         } else if (type === 2) {
    //             ns.push(vs[i].x, vs[i].y, vs[i].z);
    //             newvs.push(vs2[i].x, vs2[i].y, vs2[i].z);
    //         } else if (type === 3) {
    //             ns.push(vs[i].y, vs[i].z, vs[i].x);
    //             newvs.push(vs2[i].y, vs2[i].z, vs2[i].x);
    //         } else if (type === 4) {
    //             ns.push(vs[i].z, vs[i].x, vs[i].y);
    //             newvs.push(vs2[i].z, vs2[i].x, vs2[i].y);
    //         } else if (type === 5) {
    //             ns.push(vs[i].y, vs[i].x, vs[i].z);
    //             newvs.push(vs2[i].y, vs2[i].x, vs2[i].z);
    //         } else if (type === 6) {
    //             ns.push(vs[i].z, vs[i].y, vs[i].x);
    //             newvs.push(vs2[i].z, vs2[i].y, vs2[i].x);
    //         }
    //         ppppppppsss2.push(new Vector3(ns[i * 3], ns[i * 3 + 1], ns[i * 3 + 2]));
    //     }
    //     let minxyz = this.getPsLWbyVec3(vs);
    //     let holeIndex = null;
    //     holeIndex = [];
    //     let curr = ns.length / 3;
    //     for (i = 0; i < arr.length; i++) {
    //         if (type === 1 || type === 3 || type === 2) {
    //             circle = MeshGeomLib.getCircleByXYZ2(arr[i].radius, arr[i].x, arr[i].y);
    //             for (j = 0; j < circle.vecs.length; j += 3) {
    //                 circle.vecs[j + 2] = ns[2];
    //                 if (angle > 180) {
    //                     let vvvvv = new Vector3(circle.vecs[j + 0], circle.vecs[j + 1], circle.vecs[j + 2]);
    //                     vvvvv.applyAxisAngle(new Vector3(0, 0, 1), -(angle - 180) * Math.PI / 180);
    //                     circle.vecs[j] = vvvvv.x;
    //                     circle.vecs[j + 1] = vvvvv.y;
    //                     circle.vecs[j + 2] = vvvvv.z;
    //                 }
    //                 else if (angle > 0) {
    //                     let vvvvv = new Vector3(circle.vecs[j + 0], circle.vecs[j + 1], circle.vecs[j + 2]);
    //                     if (type === 2) {
    //                         vvvvv.applyAxisAngle(new Vector3(0, 0, 1), -angle * Math.PI / 180);
    //                     } else if (type === 3) {
    //                         vvvvv = new Vector3(arr[i].l, circle.vecs[j + 1], circle.vecs[j + 0]);
    //                         vvvvv.applyAxisAngle(new Vector3(0, 0, 1), -angle * Math.PI / 180);
    //                         if (arr[i].hasOwnProperty('h')) {
    //                             vvvvv = new Vector3(vvvvv.y + arr[i].h, vvvvv.z, vvvvv.x);
    //                         } else {
    //                             vvvvv = new Vector3(vvvvv.y, vvvvv.z, vvvvv.x);
    //                         }
    //                         if (arr[i].hasOwnProperty('z')) {
    //                             vvvvv.y -= arr[i].z;
    //                         }
    //                     } else if (type === 1) {
    //                         vvvvv = new Vector3(circle.vecs[j + 0] + arr[i].l, 0, circle.vecs[j + 1]);
    //                         vvvvv.applyAxisAngle(new Vector3(1, 0, 0), -angle * Math.PI / 180);
    //                         if (arr[i].hasOwnProperty('h')) {
    //                             vvvvv = new Vector3(vvvvv.x, vvvvv.z, vvvvv.y + arr[i].h);
    //                             if (arr[i].hasOwnProperty('xxx')) {
    //                                 vvvvv.y += arr[i].xxx;
    //                             }
    //                         }
    //                         if (arr[i].hasOwnProperty('z')) {
    //                             vvvvv.y -= arr[i].z;
    //                         }
    //                     }
    //                     circle.vecs[j] = vvvvv.x;
    //                     circle.vecs[j + 1] = vvvvv.y;
    //                     circle.vecs[j + 2] = vvvvv.z;
    //                 }

    //                 if (type === 2) {
    //                     // circle.vecs[j] += dir.x > 0?minxyz[0]:minxyz[3];
    //                     circle.vecs[j + 1] += dir.y > 0 ? minxyz[1] : minxyz[4];
    //                 }
    //                 ppppppppsss.push(new Vector3(circle.vecs[j], circle.vecs[j + 1], circle.vecs[j + 2]));
    //             }
    //             //圆心处理
    //             vv = circle.p;
    //             vv.z = ns[2];
    //             if (angle > 0) {
    //                 if (type === 2) {
    //                     vv.applyAxisAngle(new Vector3(0, 0, 1), -angle * Math.PI / 180);
    //                 } else if (type === 3) {
    //                     vv = new Vector3(arr[i].l, vv.y, vv.x);
    //                     vv.applyAxisAngle(new Vector3(0, 0, 1), -angle * Math.PI / 180);
    //                     if (arr[i].hasOwnProperty('h')) {
    //                         vv = new Vector3(vv.y + arr[i].h, vv.z, vv.x);
    //                     } else {
    //                         vv = new Vector3(vv.y, vv.z, vv.x);
    //                     }
    //                     if (arr[i].hasOwnProperty('z')) {
    //                         vv.y -= arr[i].z;
    //                     }
    //                 } else if (type === 1) {
    //                     vv = new Vector3(vv.x + arr[i].l, 0, vv.y);
    //                     vv.applyAxisAngle(new Vector3(1, 0, 0), -angle * Math.PI / 180);
    //                     if (arr[i].hasOwnProperty('h')) {
    //                         vv = new Vector3(vv.x, vv.z, vv.y + arr[i].h);
    //                         if (arr[i].hasOwnProperty('xxx')) {
    //                             vv.y += arr[i].xxx;
    //                         }
    //                     }
    //                     if (arr[i].hasOwnProperty('z')) {
    //                         vv.y -= arr[i].z;
    //                     }
    //                 }
    //             }
    //             if (type === 2) {
    //                 vv.y += dir.y > 0 ? minxyz[1] : minxyz[4];
    //             }
    //             ks = ks.concat([vv]);
    //         }
    //         ns = ns.concat(circle.vecs);
    //         holeIndex.push(curr);
    //         curr += circle.indexs;
    //     }
    //     let vertices4 = earcut(ns, holeIndex, 3);
    //     let tempNum: number = 0;
    //     let newns = [];
    //     let indics = [];
    //     if (kongs) {
    //         ks.map((vv) => {
    //             if (type == 1) { kongs.push(vv.x, vv.z, vv.y) }
    //             else if (type == 3) { kongs.push(vv.z, vv.x, vv.y); }
    //             else { kongs.push(vv.x, vv.y, vv.z); }
    //         })
    //     }
    //     indics.push(...vertices4);
    //     for (i = 0; i < ns.length; i += 3) {
    //         if (type === 1) {
    //             tempNum = ns[i + 2];
    //             ns[i + 2] = ns[i + 1];
    //             ns[i + 1] = tempNum;

    //         } else if (type === 3) {
    //             tempNum = ns[i + 2];
    //             ns[i + 2] = ns[i + 1];
    //             ns[i + 1] = tempNum;
    //             tempNum = ns[i + 1];
    //             ns[i + 1] = ns[i];
    //             ns[i] = tempNum;
    //         } else if (type === 2) {
    //             // newns.push(ns[i],ns[i+1],ns[i+2]+num);
    //         }

    //     }
    //     let len = ns.length / 3;
    //     if (!BIM.simpleMold) {
    //         for (i = 0; i < vs.length; i++) {
    //             j = i >= (vs.length - 1) ? 0 : i + 1;
    //             ns.push(vs[i].x, vs[i].y, vs[i].z);  //0
    //             ns.push(vs[j].x, vs[j].y, vs[j].z);  //1

    //             ns.push(vs2[j].x, vs2[j].y, vs2[j].z);   //2
    //             ns.push(vs2[i].x, vs2[i].y, vs2[i].z);   //3

    //             indics.push(len, len + 3, len + 1);
    //             indics.push(len + 3, len + 2, len + 1);

    //             len += 4;
    //         }
    //     }

    //     if (faces) {
    //         if (!BIM.simpleMold) {
    //             faces.push({ key: key, faces: [...vs] });
    //         } else {
    //             faces.push({ key: key, faces: [...vs] });
    //         }
    //     }
    //     return { vec: ns, indics: indics };
    // }

    static getFaceHoleNs3(vs: Vector3[], vs2: Vector3[], arr: any[], type: number = 1, angle: number = 0, dir: Vector3 = new Vector3(1, 1, 1)): any {
        let i: number, j: number, circle: any;
        let ns: number[] = [];
        let newvs: number[] = [];
        let ppppppppsss: Vector3[] = [];
        let ppppppppsss2: Vector3[] = [];
        let ppppppppsss3: Vector3[] = [];
        for (i = 0; i < vs.length; i++) {
            if (type === 1) {
                ns.push(vs[i].x, vs[i].z, vs[i].y);
                newvs.push(vs2[i].x, vs2[i].z, vs2[i].y);
            } else if (type === 2) {
                ns.push(vs[i].x, vs[i].y, vs[i].z);
                newvs.push(vs2[i].x, vs2[i].y, vs2[i].z);
            } else if (type === 3) {
                ns.push(vs[i].y, vs[i].z, vs[i].x);
                newvs.push(vs2[i].y, vs2[i].z, vs2[i].x);
            } else if (type === 4) {
                ns.push(vs[i].z, vs[i].x, vs[i].y);
                newvs.push(vs2[i].z, vs2[i].x, vs2[i].y);
            } else if (type === 5) {
                ns.push(vs[i].y, vs[i].x, vs[i].z);
                newvs.push(vs2[i].y, vs2[i].x, vs2[i].z);
            } else if (type === 6) {
                ns.push(vs[i].z, vs[i].y, vs[i].x);
                newvs.push(vs2[i].z, vs2[i].y, vs2[i].x);
            }
            ppppppppsss2.push(new Vector3(ns[i * 3], ns[i * 3 + 1], ns[i * 3 + 2]));
        }
        let minxyz = this.getPsLWbyVec3(vs);
        let holeIndex = null;
        holeIndex = [];
        let curr = ns.length / 3;

        for (i = 0; i < arr.length; i++) {
            if (type === 1 || type === 3 || type === 2) {
                circle = MeshGeomLib.getCircleByXYZ2(arr[i].radius, arr[i].x, arr[i].y);
                for (j = 0; j < circle.vecs.length; j += 3) {
                    circle.vecs[j + 2] = ns[2];
                    if (angle > 0) {
                        let vvvvv = new Vector3(circle.vecs[j + 0], circle.vecs[j + 1], circle.vecs[j + 2]);
                        if (type === 2) {
                            vvvvv.applyAxisAngle(new Vector3(0, 0, 1), -angle * Math.PI / 180);
                        } else if (type === 3) {
                            vvvvv = new Vector3(arr[i].l, circle.vecs[j + 1], circle.vecs[j + 0]);
                            vvvvv.applyAxisAngle(new Vector3(0, 0, 1), -angle * Math.PI / 180);
                            if (arr[i].hasOwnProperty('h')) {
                                vvvvv = new Vector3(vvvvv.y + arr[i].h, vvvvv.z, vvvvv.x);
                            } else {
                                vvvvv = new Vector3(vvvvv.y, vvvvv.z, vvvvv.x);
                            }
                        } else if (type === 1) {
                            vvvvv = new Vector3(circle.vecs[j + 0] + arr[i].l, 0, circle.vecs[j + 1]);
                            vvvvv.applyAxisAngle(new Vector3(1, 0, 0), -angle * Math.PI / 180);
                            if (arr[i].hasOwnProperty('h')) {
                                vvvvv = new Vector3(vvvvv.x, vvvvv.z, vvvvv.y + arr[i].h);
                                if (arr[i].hasOwnProperty('xxx')) {
                                    vvvvv.y += arr[i].xxx;
                                }
                            }
                        }
                        circle.vecs[j] = vvvvv.x;
                        circle.vecs[j + 1] = vvvvv.y;
                        circle.vecs[j + 2] = vvvvv.z;
                    }

                    if (type === 2) {
                        // circle.vecs[j] += dir.x > 0?minxyz[0]:minxyz[3];
                        circle.vecs[j + 1] += dir.y > 0 ? minxyz[1] : minxyz[4];
                    }
                    ppppppppsss.push(new Vector3(circle.vecs[j], circle.vecs[j + 1], circle.vecs[j + 2]));
                }
            }
            ns = ns.concat(circle.vecs);
            holeIndex.push(curr);
            curr += circle.indexs;
        }
        let vertices4 = earcut(ns, holeIndex, 3);
        let tempNum: number = 0;
        let newns = [];
        let indics = [];
        indics.push(...vertices4);
        for (i = 0; i < ns.length; i += 3) {
            if (type === 1) {
                tempNum = ns[i + 2];
                ns[i + 2] = ns[i + 1];
                ns[i + 1] = tempNum;

            } else if (type === 3) {
                tempNum = ns[i + 2];
                ns[i + 2] = ns[i + 1];
                ns[i + 1] = tempNum;
                tempNum = ns[i + 1];
                ns[i + 1] = ns[i];
                ns[i] = tempNum;
            } else if (type === 2) {
                // newns.push(ns[i],ns[i+1],ns[i+2]+num);
            }

        }
        // if(isdraw){
        //     PothoLingDebugUtil.createPoints(ppppppppsss2);
        //     PothoLingDebugUtil.createPoints(ppppppppsss,0x0000ff);
        //     PothoLingDebugUtil.createPoints(ppppppppsss3,0x00ff00);
        // }
        let len = ns.length / 3;
        for (i = 0; i < vs.length; i++) {
            j = i >= (vs.length - 1) ? 0 : i + 1;
            ns.push(vs[i].x, vs[i].y, vs[i].z);  //0
            ns.push(vs[j].x, vs[j].y, vs[j].z);  //1

            ns.push(vs2[j].x, vs2[j].y, vs2[j].z);   //2
            ns.push(vs2[i].x, vs2[i].y, vs2[i].z);   //3

            indics.push(len, len + 3, len + 1);
            indics.push(len + 3, len + 2, len + 1);

            len += 4;
        }
        return { vec: ns, indics: indics };
    }


    /**
    * vs 面的坐标组  arr 孔的对象数组 type 0无1xz2xy3yz4zx5yx6zy
    */
    static getFaceHoleNs2(vs: Vector3[], arr: any[], type: number = 1, num: number = 0, idd: number = 0, isleft: number = 1, cs: Vector3[] = null, ks: number[] = null, faces: any[] = null, key: string = ''): any {
        let i: number, j: number, circle: any;
        let ns: number[] = [];
        let vvs: Vector3[] = [];
        let newvs: Vector3[] = [];
        let kongs: Vector3[] = [];
        for (i = 0; i < vs.length; i++) {
            if (type === 1) {
                ns.push(vs[i].x, vs[i].z, vs[i].y);
                newvs.push(new Vector3(vs[i].x, vs[i].y + num, vs[i].z));
            } else if (type === 2) {
                ns.push(vs[i].x, vs[i].y, vs[i].z);
                newvs.push(new Vector3(vs[i].x, vs[i].y, vs[i].z + num));
            } else if (type === 3) {
                ns.push(vs[i].y, vs[i].z, vs[i].x);
                newvs.push(new Vector3(vs[i].x + num, vs[i].y, vs[i].z));
            } else if (type === 4) {
                ns.push(vs[i].z, vs[i].x, vs[i].y);
                newvs.push(new Vector3(vs[i].x, vs[i].y + num, vs[i].z));
            } else if (type === 5) {
                ns.push(vs[i].y, vs[i].x, vs[i].z);
                newvs.push(new Vector3(vs[i].x, vs[i].y, vs[i].z + num));
            } else if (type === 6) {
                ns.push(vs[i].z, vs[i].y, vs[i].x);
                newvs.push(new Vector3(vs[i].x + num, vs[i].y, vs[i].z));
            }
        }
        let holeIndex = null;
        let tempNum: number = 0;
        holeIndex = [];
        let curr = ns.length / 3;
        for (i = 0; i < arr.length; i++) {
            if (type === 1 || type === 3 || type === 2) {
                circle = MeshGeomLib.getCircleByXYZ4(arr[i]);
                for (j = 0; j < circle.vecs.length; j += 3) {
                    circle.vecs[j + 2] = ns[2];
                    if (idd === 1) {
                        tempNum = circle.vecs[j + 0];
                        circle.vecs[j + 0] = circle.vecs[j + 1];
                        circle.vecs[j + 1] = tempNum;
                    }
                }
            }
            ns = ns.concat(circle.vecs);
            holeIndex.push(curr);
            curr += circle.indexs;
            kongs = kongs.concat([new Vector3(idd === 1 ? arr[i].curves[0].aY : arr[i].curves[0].aX, idd === 1 ? arr[i].curves[0].aX : arr[i].curves[0].aY, ns[2])]);
        }
        if (cs) {
            cs.map((c) => {
                vvs.push(new Vector3(idd == 1 ? c.y : c.x, idd == 1 ? c.x : c.y, ns[2]));
            })
        }
        let vertices4 = earcut(ns, holeIndex, 3);
        let newns = [];
        let indics = [];
        if (ks) {
            kongs.map((vv) => {
                if (type == 1) { ks.push(vv.x, vv.z, vv.y) }
                else if (type == 3) { ks.push(vv.z, vv.x, vv.y); }
                else { ks.push(vv.x, vv.y, vv.z); }
            })
            kongs.map((vv) => {
                if (type == 1) { ks.push(vv.x, vv.z + num, vv.y) }
                else if (type == 3) { ks.push(vv.z + num, vv.x, vv.y); }
                else { ks.push(vv.x, vv.y, vv.z + num); }
            })
        }
        indics.push(...vertices4.reverse());
        for (i = 0; i < ns.length; i += 3) {
            if (type === 1) {
                tempNum = ns[i + 2];
                ns[i + 2] = ns[i + 1];
                ns[i + 1] = tempNum;
                if (num > 0) {
                    newns.push(ns[i], ns[i + 1] + num, ns[i + 2]);
                }
            } else if (type === 3) {
                tempNum = ns[i + 2];
                ns[i + 2] = ns[i + 1];
                ns[i + 1] = tempNum;
                tempNum = ns[i + 1];
                ns[i + 1] = ns[i];
                ns[i] = tempNum;
                if (num > 0) {
                    newns.push(ns[i] + num, ns[i + 1], ns[i + 2]);
                }
            } else if (type === 2) {
                newns.push(ns[i], ns[i + 1], ns[i + 2] + num);
            }
        }

        if ((num > 0 && !BIM.simpleMold) || isleft == 2) {
            let len = ns.length / 3;
            ns.push(...newns);
            vertices4.reverse();
            indics.push(...vertices4.map((value) => { value += len; return value; }));
            len = ns.length / 3;
            for (i = 0; i < vs.length; i++) {
                let d = i;
                let dd = i + 1 >= vs.length ? 0 : i + 1;
                ns.push(vs[d].x, vs[d].y, vs[d].z);  //0
                ns.push(vs[dd].x, vs[dd].y, vs[dd].z);  //1

                ns.push(newvs[dd].x, newvs[dd].y, newvs[dd].z);   //2
                ns.push(newvs[d].x, newvs[d].y, newvs[d].z);   //3

                indics.push(len, len + 3, len + 1);
                indics.push(len + 3, len + 2, len + 1);

                len += 4;
            }
        } else {
            if (isleft == 0 && BIM.simpleMold) {
                ns = [];
                indics = [];
                ns.push(...newns);
                vertices4.reverse();
                indics.push(...vertices4.reverse());
            }
        }
        if (faces) {
            if (!BIM.simpleMold || isleft == 2) {
                if (key == AK.p_dingpbfbk) {
                    if (isleft == 0) {
                        faces.push({ key: key, faces: [...newvs] });
                    } else {
                        faces.push({ key: key, faces: [...vs] });
                    }
                } else {
                    faces.push({ key: key, faces: [...vs] });
                    faces.push({ key: key, faces: [...newvs] });
                }
            } else {
                if (isleft == 0) {
                    faces.push({ key: key, faces: [...newvs] });
                } else {
                    faces.push({ key: key, faces: [...vs] });
                }
            }
        }
        return { vec: ns, indics: indics };
    }
    /**
     * vs 面的坐标组  arr 孔的对象数组 type 0无1xz2xy3yz4zx5yx6zy
     */
    static getFaceHoleNs(vs: Vector3[], arr: any[], type: number = 1, num: number = 0): any {
        let i: number, j: number, circle: any;
        let ns: number[] = [];
        let newvs: Vector3[] = [];
        for (i = 0; i < vs.length; i++) {
            if (type === 1) {
                ns.push(vs[i].x, vs[i].z, vs[i].y);
                newvs.push(new Vector3(vs[i].x, vs[i].y + num, vs[i].z));
            } else if (type === 2) {
                ns.push(vs[i].x, vs[i].y, vs[i].z);
                newvs.push(new Vector3(vs[i].x, vs[i].y, vs[i].z + num));
            } else if (type === 3) {
                ns.push(vs[i].y, vs[i].z, vs[i].x);
                newvs.push(new Vector3(vs[i].x + num, vs[i].y, vs[i].z));
            } else if (type === 4) {
                ns.push(vs[i].z, vs[i].x, vs[i].y);
                newvs.push(new Vector3(vs[i].x, vs[i].y + num, vs[i].z));
            } else if (type === 5) {
                ns.push(vs[i].y, vs[i].x, vs[i].z);
                newvs.push(new Vector3(vs[i].x, vs[i].y, vs[i].z + num));
            } else if (type === 6) {
                ns.push(vs[i].z, vs[i].y, vs[i].x);
                newvs.push(new Vector3(vs[i].x + num, vs[i].y, vs[i].z));
            }

        }
        let holeIndex = null;
        holeIndex = [];
        let curr = ns.length / 3;
        let vvvvv: Vector3;
        let ppppppppsss: Vector3[] = [];
        let ppppppppsss2: Vector3[] = [];
        for (i = 0; i < arr.length; i++) {
            if (type === 1 || type === 3 || type === 2) {
                circle = MeshGeomLib.getCircleByXYZ2(arr[i].radius, arr[i].y, arr[i].x);
                for (j = 0; j < circle.vecs.length; j += 3) {
                    // if(arr[i]['angle']){
                    vvvvv = new Vector3(circle.vecs[j + 0], circle.vecs[j + 1], circle.vecs[j + 2]);
                    ppppppppsss2.push(vvvvv.clone());
                    vvvvv.applyAxisAngle(new Vector3(0, 1, 0), 120 * Math.PI / 180);
                    ppppppppsss.push(vvvvv);

                    // }
                    circle.vecs[j + 2] = ns[2];
                }
            }
            ns = ns.concat(circle.vecs);
            holeIndex.push(curr);
            curr += circle.indexs;
        }
        // PothoLingDebugUtil.createPoints(ppppppppsss2);
        // PothoLingDebugUtil.createPoints(ppppppppsss);
        let vertices4 = earcut(ns, holeIndex, 3);
        let tempNum: number = 0;
        let newns = [];
        let indics = [];
        indics.push(...vertices4.reverse());
        for (i = 0; i < ns.length; i += 3) {
            if (type === 1) {
                tempNum = ns[i + 2];
                ns[i + 2] = ns[i + 1];
                ns[i + 1] = tempNum;
                if (num > 0) {
                    newns.push(ns[i], ns[i + 1] + num, ns[i + 2]);
                }
            } else if (type === 3) {
                tempNum = ns[i + 2];
                ns[i + 2] = ns[i + 1];
                ns[i + 1] = tempNum;
                tempNum = ns[i + 1];
                ns[i + 1] = ns[i];
                ns[i] = tempNum;
                if (num > 0) {
                    newns.push(ns[i] + num, ns[i + 1], ns[i + 2]);
                }
            } else if (type === 2) {
                newns.push(ns[i], ns[i + 1], ns[i + 2] + num);
            }
        }
        if (num > 0) {
            let len = ns.length / 3;
            ns.push(...newns);
            vertices4.reverse();
            indics.push(...vertices4.map((value) => { value += len; return value; }));
            len = ns.length / 3;
            for (i = 0; i < vs.length; i++) {
                let d = i;
                let dd = i + 1 >= vs.length ? 0 : i + 1;
                ns.push(vs[d].x, vs[d].y, vs[d].z);  //0
                ns.push(vs[dd].x, vs[dd].y, vs[dd].z);  //1

                ns.push(newvs[dd].x, newvs[dd].y, newvs[dd].z);   //2
                ns.push(newvs[d].x, newvs[d].y, newvs[d].z);   //3

                indics.push(len, len + 3, len + 1);
                indics.push(len + 3, len + 2, len + 1);

                len += 4;
            }
        }
        return { vec: ns, indics: indics };
    }
    static getCircleArray(radius: number, p: Vector3 = new Vector3(), type: number = 0): any[] {
        let arr = MeshGeomLib.getArcPoints(new Vector3(-radius, 0, 0), new Vector3(0, radius, 0), new Vector3(radius, 0, 0));
        let arr2 = MeshGeomLib.getArcPoints(new Vector3(-radius, 0, 0), new Vector3(0, -radius, 0), new Vector3(radius, 0, 0));
        arr2.shift();
        arr2.pop();
        arr2.reverse();
        arr = arr.concat(arr2);
        arr = this.getMeshVertices(arr);
        return arr;
    }
    /**
    * radius 圆的半径  num在xyz相对于0的距离 type 0无1xz2xyz3yz4zx5yx6zy
    */
    static getCircleByXYZ(radius: number, num: number = 0, num2: number, type: number = 0): any[] {
        let arr;
        let arr2;
        arr = MeshGeomLib.getArcPoints(new Vector3(num, num2 + radius, 0), new Vector3(num + radius, num2 + 2 * radius, 0), new Vector3(num + 2 * radius, num2 + radius, 0), 10);
        arr2 = MeshGeomLib.getArcPoints(new Vector3(num, num2 + radius, 0), new Vector3(num + radius, num2, 0), new Vector3(num + 2 * radius, num2 + radius, 0), 10);
        arr2.shift();
        arr2.pop();
        arr2.reverse();
        arr = arr.concat(arr2);
        arr = this.getMeshVertices(arr, type);
        return arr;
    }
    /**
     * radius 圆的半径  num在xyz相对于0的距离 type 0无1xz2xyz3yz4zx5yx6zy
     */
    static getCircleByXYZ2(radius: number, num: number = 0, num2: number, type: number = 0): any {
        let i: number, j: number;
        let arr = [];
        let holes = [];
        let holeIndex = [];
        let path = new Path();
        path.moveTo(num, num2).absarc(num, num2, radius, 0.0, 2 * Math.PI, false);
        let v2s = path.getPoints(6);
        for (let v2 of v2s) {
            arr.push(v2.x, v2.y, 0);
        }
        return { vecs: arr, indexs: v2s.length };
    }
    /**
     * radius 圆的半径  num在xyz相对于0的距离 type 0无1xz2xyz3yz4zx5yx6zy
     */
    static getCircleByXYZ4(path: Path): any {
        let arr = [];
        let v2s = path.getPoints(6);
        for (let v2 of v2s) {
            arr.push(v2.x, v2.y, 0);
        }
        return { vecs: arr, indexs: v2s.length };
    }
    /**
     * radius 圆的半径  画圆柱点 type 1xz2xy3yz
     */
    static getCircleByXYZ3(radius: number, v: Vector3, h: number, type: number = 1, angle: number = 0, dir: number = 1): any {
        let i: number, j: number, tempNum, v3: Vector3;
        let arr = [], newarr = [];
        let holes = [];
        let holeIndex = [];
        let path = new Path();
        if (type === 1) {
            path.moveTo(v.x, v.z).absarc(v.x, v.z, radius, 0.0, 2 * Math.PI, false);
        } else if (type === 2) {
            path.moveTo(v.x, v.y).absarc(v.x, v.y, radius, 0.0, 2 * Math.PI, false);
        } else if (type === 3) {
            path.moveTo(v.y, v.z).absarc(v.y, v.z, radius, 0.0, 2 * Math.PI, false);
        }
        let mat = new Matrix4();
        mat.identity();//
        if (dir > 0) {
            mat.makeRotationZ((-(90 - angle)) * Math.PI / 180);
        } else {
            mat.makeRotationX(((90 - angle)) * Math.PI / 180);
        }
        let matt = new Matrix4();
        matt.makeTranslation(0, 0, 0);
        mat.copyPosition(matt);
        let v2s = path.getPoints(6);
        for (let v2 of v2s) {
            if (type === 1) {
                arr.push(v2.x, v2.y, v.y);
                newarr.push(v2.x, v2.y, v.y + h)
            } else if (type === 2) {
                arr.push(v2.x, v2.y, v.z);
                newarr.push(v2.x, v2.y, v.z + h)
            } else if (type === 3) {
                arr.push(v.x, v2.x, v2.y);
                newarr.push(v.x + h, v2.x, v2.y)
            }
        }
        if (angle !== 0) {
            for (i = 0; i < arr.length; i += 3) {
                v3 = new Vector3(arr[i + 0], arr[i + 2], arr[i + 1]);
                v3 = v3.sub(v);
                v3 = v3.applyMatrix4(mat);
                v3 = v3.add(v);
                if (dir > 0) {
                    arr[i + 0] = v3.x; arr[i + 2] = v3.y;
                } else {
                    arr[i + 1] = v3.z; arr[i + 2] = v3.y;
                }

                v3 = new Vector3(newarr[i + 0], newarr[i + 2], newarr[i + 1]);
                v3 = v3.sub(v);
                v3 = v3.applyMatrix4(mat);
                v3 = v3.add(v);
                if (dir > 0) {
                    newarr[i + 0] = v3.x; newarr[i + 2] = v3.y;
                } else {
                    newarr[i + 1] = v3.z; newarr[i + 2] = v3.y;
                }
            }
        }
        let vertices = earcut(arr, [], 3);
        let indics = [];
        let ns: number[] = [];
        indics.push(...vertices);
        for (i = 0; i < arr.length; i += 3) {
            if (type === 1) {
                tempNum = arr[i + 2];
                arr[i + 2] = arr[i + 1];
                arr[i + 1] = tempNum;

                tempNum = newarr[i + 2];
                newarr[i + 2] = newarr[i + 1];
                newarr[i + 1] = tempNum;
            }
        }
        ns.push(...arr);
        indics.push(...vertices.map((value) => { value += (ns.length) / 3; return value; }));
        // indics.push(...vertices.reverse());

        ns.push(...newarr);
        let len = (ns.length) / 3;
        for (i = 0; i < arr.length; i += 3) {
            let d = i;
            let dd = i + 3 >= arr.length ? 0 : i + 3;
            ns.push(arr[d], arr[d + 1], arr[d + 2]);  //0
            ns.push(arr[dd], arr[dd + 1], arr[dd + 2]);  //1

            ns.push(newarr[dd], newarr[dd + 1], newarr[dd + 2]);   //2
            ns.push(newarr[d], newarr[d + 1], newarr[d + 2]);   //3

            indics.push(len + 1, len + 3, len);
            indics.push(len + 1, len + 2, len + 3);
            len += 4;
        }
        return { vec: ns, indics: indics };
    }

     /**
     * 获取孔
     * @param r 
     * @param rpos 
     * @param holes 
     * @param type 0 x 1 y 2 z
     */
     static getHoles(r: string, rpos: string, holes: Path[], num: number = 0, type: number = 0, len: number = 0,
        obj: any = null, key: string = null, offsetXY: number[] = null, isreverse: boolean = false, centres: Vector3[] = null): void {
        let holePath: Path;
        let cdr: string[];
        let index: number = -1;
        let i: number, xv: number, yv: number, widthR: number, hightR: number, gmtR: number;
        let gmtpos = AModelFmulaUtils.getHolesbyExpress(rpos, len, 2, obj, key, isreverse ? 10000 : 0);
        if (gmtpos && gmtpos.length > 0) {
            for (i = 0; i < gmtpos.length; i++) {
                xv = type === 1 ? num : gmtpos[i];
                yv = type === 1 ? gmtpos[i] : num;
                if (offsetXY) {
                    if (offsetXY.length > 2 && offsetXY[2] === 1) {
                        xv = xv + offsetXY[0];
                        yv = offsetXY[1] - yv;
                    } else {
                        xv = xv + offsetXY[0];
                        yv = yv + offsetXY[1];
                    }
                }
                gmtR = Number(r);
                if (gmtpos[i] > (len - gmtR - 2)) {
                    continue;
                }
                holePath = new Path();
                holePath.moveTo(xv, yv)
                    .absarc(xv, yv, gmtR / 2, 0, Math.PI * 2, true);
                if (centres) centres.push(new Vector3(xv, yv));
                holes.push(holePath);
            }
        }
    }

    /**
     * 平面连续点 type 1是z点在y  2是正常 1xz2xyz3yz4zx5yx6zy
     */
    static getMeshVertices(arr: Vector3[], type: number = 1): Vector3[] {
        let vecs: Vector3[] = [];
        let i: number;
        for (i = 0; i < arr.length; i++) {
            if (type === 1) {
                vecs.push(new Vector3(arr[i].x, arr[i].z, arr[i].y));
            } else if (type === 2) {
                vecs.push(new Vector3(arr[i].x, arr[i].y, arr[i].z));
            } else if (type === 3) {
                vecs.push(new Vector3(arr[i].z, arr[i].x, arr[i].y));
            } else if (type === 4) {
                vecs.push(new Vector3(arr[i].y, arr[i].z, arr[i].x));
            } else if (type === 5) {
                vecs.push(new Vector3(arr[i].y, arr[i].x, arr[i].z));
            } else if (type === 6) {
                vecs.push(new Vector3(arr[i].z, arr[i].y, arr[i].x));
            }
        }
        // for(i=arr.length-1;i>-1;i--){
        //     if(type === 1){
        //         vecs.push(new Vector3(arr[i].x,arr[i].z+h,arr[i].y));
        //     }else{
        //         vecs.push(new Vector3(arr[i].x,arr[i].y+h,arr[i].z));
        //     }
        // }
        return vecs;
    }

    /**
     * 矩阵角度转换 angle 弧度 pt 定位点
     */
    static getMatrixRotate(angle: number, pt?: Vector3): Matrix4 {
        pt = pt || new Vector3(0, 0, 0)
        let mat = new Matrix4();
        mat.identity();//
        mat.makeRotationZ((-(90 - angle)) * Math.PI / 180);
        let matt = new Matrix4();
        matt.makeTranslation(pt.x, pt.y, pt.z);
        mat.copyPosition(matt);
        return mat;
    }

    /**
     * 三点画圆弧
     */
    static getArcPoints(sp: Vector3, mp: Vector3, ep: Vector3, deltaAngle: number = 5): any[] {
        let i: number, j: number;
        let points = new Array();
        let a = sp;
        let b = mp;
        let c = ep;
        let arr = [];
        let cp = MeshGeomLib.computeCircleCenter(sp, mp, ep);
        let r = Math.sqrt((cp.x - sp.x) * (cp.x - sp.x) + (cp.y - sp.y) * (cp.y - sp.y));
        let ab = (a.clone()).sub(cp);
        let bc = (c.clone()).sub(cp);
        let fromRot = Math.atan2(ab.y, ab.x);
        let toRot = Math.atan2(bc.y, bc.x);
        let sm = (b.clone()).sub(a);
        let me = (c.clone()).sub(b);
        let up = ((me.clone()).cross(sm)).normalize();
        if (up.dot(new Vector3(0, 0, 1)) < 0) {
            //+
            while (fromRot > toRot) {
                toRot += Math.PI * 2;
            }
        } else {
            //-
            while (fromRot < toRot) {
                toRot -= Math.PI * 2;
            }
        }
    /*弧角*/let arcAngle = toRot - fromRot;
    /*弧长比周长*/let arcScale = Math.abs(arcAngle) / (2 * Math.PI);
    /*弧长*/let arcLength = arcScale * 2 * Math.PI * r;

        let hArcCount = Math.abs(Math.ceil(arcAngle / (deltaAngle * Math.PI / 180.0)));
        let dHAngle = arcAngle / hArcCount;
        let hRot = fromRot;
        let b1 = null;
        arr.push(sp);
        for (j = 0; j < hArcCount - 1; j++) {
            hRot += dHAngle;
            b1 = new Vector3(cp.x + Math.cos(hRot) * r, cp.y + Math.sin(hRot) * r, 0);
            arr.push(b1);
        }
        arr.push(ep);
        return arr;
    }
    /**
     * 根据圆弧上的三点求圆心
     */
    static computeCircleCenter(p: Vector3, q: Vector3, t: Vector3): Vector3 {
        let a = p.x + q.x;
        let b = p.x - q.x;
        let c = p.y + q.y;
        let d = p.y - q.y;
        let e = q.x + t.x;
        let f = q.x - t.x;
        let g = q.y + t.y;
        let h = q.y - t.y;
        let cp = new Vector3();
        cp.y = (a * b * f - b * e * f + c * d * f - b * g * h) / (2 * (d * f - b * h));
        cp.x = (c * d - 2 * cp.y * d + a * b) / (2 * b);
        return cp;
    }

    static rayCrossLine(pos: Vector3, dir: Vector3, p0: Vector3, p1: Vector3, epsilon: number = 0.0001): Vector3 {
        var nearzero = 0.00001;
        // epsilon = epsilon || 0.0001;
        var dir0 = dir;
        var dir1 = (p1.clone()).sub(p0);
        var up = ((dir0.clone()).cross(dir1)).clone().normalize();
        var diff = (pos.clone()).sub(p0);
        if (Math.abs(diff.dot(up)) > epsilon) return null;//异面
        var n1t = ((dir0.clone()).cross(up)).clone().normalize();
        var base = dir1.dot(n1t);
        if (Math.abs(base) < nearzero) return null;// 同面平衡
        var scale = diff.dot(n1t) / base;

        var r = MeshGeomLib.lerp(p0, p1, scale);

        var length1 = (r.clone()).sub(pos).dot(dir);

        if (length1 < -epsilon) return null; //负方向
        return r;
    }

    static CalculateNormal(vertices: Vector3[], epsilon: number) {
        epsilon = epsilon || 0.0001;
        var i = 0;
        var a: Vector3;
        var b: Vector3;
        var ab: Vector3;
        var normal = null;
        var vsize = vertices.length;
        for (i = 0; i < vsize; i++) {
            a = vertices[(i - 1 + vsize) % vsize].clone();
            b = vertices[i].clone();
            ab = b.sub(a);
            if (ab.lengthSq() > 0)
                break;
        }
        while (i < vsize) {
            var c = vertices[i + 0].clone();
            var d = vertices[(i + 1) % vsize].clone();
            normal = ab.cross(d.sub(c));
            if (normal.lengthSq() > epsilon) {
                break;
            }
            i++;
        }
        if (normal == null) {
            return;
        }
        normal = normal.clone().normalize();
        return normal;
    }

    /**
     * 是否点在一个图形里
     */
     static IsPointInPolygon(point: Vector2, polygon: Vector2[]): boolean {
        if (point == null || polygon == null) {
            return false;
        }
        if (polygon.length < 3) {
            return false;
        }
        var max_point = polygon.length - 1;
        var total_angle = this.GetAngle(polygon[max_point].x, polygon[max_point].y, point.x, point.y, polygon[0].x, polygon[0].y);
        for (var i = 0; i < max_point; i++) {
            total_angle += this.GetAngle(polygon[i].x, polygon[i].y, point.x, point.y, polygon[i + 1].x, polygon[i + 1].y);
        }
        //   console.log('total_angle_____'+total_angle+'_____'+total_angle*Math.PI/180)
        return Math.abs(total_angle) > 1;
    }

    static GetAngle(Ax: number, Ay: number, Bx: number, By: number, Cx: number, Cy: number): number {
        let BAx = Ax - Bx;
        let BAy = Ay - By;
        let BCx = Cx - Bx;
        let BCy = Cy - By;
        let dot_product = BAx * BCx + BAy * BCy;//点积
        let cross_product = BAx * BCy - BAy * BCx;//叉乘
        return Math.atan2(cross_product, dot_product);//求两个向量得弧度值（夹角）
    }

    static pointExpand(vertices: Vector3[], normal: Vector3, value: number, isloop: boolean): Vector3[] {
        if (vertices.length < 3)
            return;
        var i: number;
        var copy = [];
        var vertices2 = [];
        //isloop为false的时候，头尾两个点只计算平移，不计算缩小
        if (isloop) {
            copy.push(vertices[vertices.length - 1].clone());
        } else {
            copy.push((vertices[0].clone()).add((vertices[0].clone()).sub(vertices[1])));
        }
        for (i = 0; i < vertices.length; i++) {
            copy.push(vertices[i].clone());
        }
        if (isloop) {
            copy.push(vertices[0].clone());
        } else {
            copy.push((vertices[vertices.length - 1].clone()).add((vertices[vertices.length - 1].clone()).sub(vertices[vertices.length - 2])));
        }
        // vertices.length = 0;
        for (i = 1; i < copy.length - 1; i++) {
            var a = copy[i - 1].clone();
            var b = copy[i + 0].clone();
            var c = copy[i + 1].clone();

            var p = ((b.clone()).sub(a).cross(normal)).clone().normalize();
            var q = ((c.clone()).sub(b).cross(normal)).clone().normalize();
            var n = ((p.clone()).add(q)).clone().normalize();

            var out = MeshGeomLib.mul(p, Math.abs(value));

            var cp = MeshGeomLib.rayCrossLine(b, n, (a.clone()).add(out), (b.clone()).add(out));

            if (cp != null) {
                var bevel = MeshGeomLib.sign(value) * cp.sub(b).length();
                vertices2.push(b.add(MeshGeomLib.mul(n, bevel)));
            } else {
                vertices2.push(b.add(MeshGeomLib.mul(out, value)));
            }
        }
        return vertices2;
    }


    static sign(value: number): number {
        return value < 0 ? -1 : 1;
    }

    static mul(a: Vector3, scale: number): Vector3 {
        return new Vector3(a.x * scale, a.y * scale, a.z * scale);
    }

    static lerp(a: Vector3, b: Vector3, scale: number): Vector3 {
        return MeshGeomLib.mul((b.clone()).sub(a), scale).add(a);
    }



}